package com.jie.server.core;

import com.jie.server.core.constant.ReleasableUrlConstant;
import com.jie.server.core.entity.SessionNode;
import com.jie.server.core.selector.ServerSelector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.nio.channels.SelectionKey;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author XieZhiJie
 * @date 2022/04/22 11:45
 */
public class ServerApplication {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServerSelector.class);

    /**
     * spring的ioc容器
     */
    private static ApplicationContext APPLICATION_CONTEXT;

    /**
     * 服务的session
     */
    public static final Map<Integer, SessionNode> SESSION = new ConcurrentHashMap<>(16);

    /**
     * threadLocal用于一个线程内存key
     */
    public static final ThreadLocal<SelectionKey> SELECTION_KEY_THREAD_LOCAL = new ThreadLocal<>();

    public static final Set<String> RELEASABLE_URL_SEY = new HashSet<>();

    /**
     * 服务器状态
     */
    public static boolean SERVER_STATE = true;

    static {
        // 装载可放行请求
        RELEASABLE_URL_SEY.add(ReleasableUrlConstant.LOGIN);
        RELEASABLE_URL_SEY.add(ReleasableUrlConstant.REGISTER);
    }

    /**
     * 类装载后开始启动selector
     */
    public static void start() {
        LOGGER.info("mvc类装载开始...");
        try (
                ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:application-context.xml")
        ) {
            APPLICATION_CONTEXT = classPathXmlApplicationContext;
            LOGGER.info("mvc类装载结束...");
            // 进入selector
            ServerSelector.run();
        } catch (Exception e) {
            LOGGER.error("mvc类装载失败...");
            // 装在失败则启动失败
            ServerApplication.SERVER_STATE = false;
        }
        SELECTION_KEY_THREAD_LOCAL.remove();
        LOGGER.info("服务器关闭...");
    }

    /**
     * 得到装载了mvc类的spring ioc容器
     * @return 返回ioc容器
     */
    public static ApplicationContext getApplicationContext() {
        return APPLICATION_CONTEXT;
    }

}
